package com.neusoft.neuiotms.common.service.impl;

import java.lang.reflect.Field;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;

import com.neusoft.bizcore.web.support.Searchable;
import com.neusoft.neuiotms.common.dto.AuditLogDTO;
import com.neusoft.neuiotms.common.model.AuditLog;
import com.neusoft.neuiotms.common.repository.AuditLogRepository;
import com.neusoft.neuiotms.common.service.AuditLogService;

@Service
public class AuditLogServiceImpl implements AuditLogService {

    @Autowired
    private AuditLogRepository auditLogRepository;

    @Override
    public AuditLogDTO create(AuditLogDTO dto) {
        final AuditLog model = this.toModel(dto);
        this.auditLogRepository.save(model);
        return this.toDTO(model);
    }

    @Override
    public Page<AuditLogDTO> search(Pageable pageable, Searchable searchable) {
        final Page<AuditLog> page = this.auditLogRepository.search(pageable, searchable);

        final List<AuditLog> modelList = page.getContent();
        final List<AuditLogDTO> dtoList = modelList.stream().map(it -> this.toDTO(it)).collect(Collectors.toList());
        final long totalElements = page.getTotalElements();

        Pageable p = null;
        try {
            final Field pageableField = PageImpl.class.getSuperclass().getDeclaredField("pageable");
            pageableField.setAccessible(true);
            p = (Pageable) pageableField.get(page);
        } catch (NoSuchFieldException | SecurityException | IllegalArgumentException | IllegalAccessException e) {
        }

        final Page<AuditLogDTO> dtoPage = new PageImpl<>(dtoList, p, totalElements);
        return dtoPage;

    }

    private AuditLogDTO toDTO(AuditLog model) {
        final AuditLogDTO dto = new AuditLogDTO();
        dto.setId(model.getId());
        dto.setLogTime(model.getLogTime());
        dto.setUser(model.getUser());
        dto.setModule(model.getModule());
        dto.setOpText(model.getOpText());
        dto.setOpType(model.getOpType());
        dto.setRemoteIp(model.getRemoteIp());
        return dto;
    }

    private AuditLog toModel(AuditLogDTO dto) {
        final AuditLog model = new AuditLog();
        model.setLogTime(new Date());
        model.setUser(dto.getUser());
        model.setModule(dto.getModule());
        model.setOpText(dto.getOpText());
        model.setOpType(dto.getOpType());
        model.setRemoteIp(dto.getRemoteIp());
        return model;
    }

}
